<!DOCTYPE html>
<meta charset="utf-8">
<title>力导向图</title>
<style>

    .node {
        cursor: pointer;
        stroke: #3182bd;
        stroke-width: 1.5px;
    }

    .link {
        fill: none;
        stroke: #9ecae1;
        stroke-width: 1.5px;
    }

</style>
<body style="overflow-x: hidden ;overflow-y: hidden">
<script src="VIS/dist/d3.v3.min.js"></script>
<script>

    var width = 1560,
        height = 800,
        root;

    var force = d3.layout.force()
        // .size([width, height])
        // .on("tick", tick);
        .size([width, height])//作用域的大小
        .linkDistance(200)//连接线长度
        .charge(-1000)//顶点的电荷数。该参数决定是排斥还是吸引，数值越小越互相排斥
        .on("tick", tick)//指时间间隔，隔一段时间刷新一次画面
        .start();//开始转换
    var zoom = d3.behavior.zoom()//缩放配置，
        .scaleExtent([0.4, 2])//缩放比例
        .on("zoom", zoomed);

    function zoomed() {//缩放函数
// .selectAll("g")
        svg.selectAll("g").attr("transform",//svg下移动大小
            "scale(" + d3.event.scale + ")");
        /*console.log(d3.event.translate+"/"+d3.event.scale);*/
    }

    var svg = d3.select("body").append("svg")
        // .attr("width", width)
        // .attr("height", height);
        .attr("preserveAspectRatio", "none")
        .attr("viewBox", "0 0 1920 1000")
        .attr("style", "max-width: 100%; height: auto; height: intrinsic;")
        .call(zoom)
        //禁止双击放大
        .on("dblclick.zoom", () => {});
//天网情报智能分析系统


    //添加标记以表明这是一个有向图
    svg.append("defs").selectAll("marker")
        .data(["arrow"])
        .enter().append("marker")
        .attr("id", function (d) {
            return d;
        })
        .attr("viewBox", "0 -5 10 10")
        .attr("refX", 25)
        .attr("refY", -1)
        .attr("markerWidth", 12)
        .attr("markerHeight", 12)
        .attr("orient", "auto")
        .append("path")
        .attr("stroke-width", 2)//箭头宽度
        .attr("d", "M0,-5L10,0L0,5")
        .attr('fill', '#000000');//箭头颜色;

    // svg.append("defs").append("g").selectAll(".edgepath")
    var link = svg.selectAll(".link"),
        node = svg.selectAll(".node");
    var svg_text = svg.selectAll('text');
    // var svg_edgepath = svg.selectAll(".edgepath");
    jsontest = {
        "nodes": [{"group": "知识图谱", "id": 0, "label": "知识图谱", "x": 469, "y": 410}, {
            "group": "Event",
            "id": 1,
            "label": "市场经济"
        }, {"group": "关键词", "id": 2, "label": "关键词", "color": "#F8F8FF", "shape": "box"}, {
            "group": "Event",
            "id": 3,
            "label": "发表演讲"
        }, {"group": "Event", "id": 4, "label": "为中心"}, {"group": "Event", "id": 5, "label": "表示进行"}, {
            "group": "Event",
            "id": 6,
            "label": "暗示有"
        }, {"group": "Event", "id": 7, "label": "有可能"}, {"group": "Event", "id": 8, "label": "拥有"}, {
            "group": "Event",
            "id": 9,
            "label": "要动中国"
        }, {"group": "Event", "id": 10, "label": "制定规划"}, {
            "group": "Event",
            "id": 11,
            "label": "有利于提升"
        }, {"group": "Event", "id": 12, "label": "反市场"}, {
            "group": "Event",
            "id": 13,
            "label": "政府",
            'children': [{'name': '压垮意志', "id": 14}]
        }, {
            "group": "Event",
            "id": 14,
            "label": "压垮意志"
        }, {"group": "Event", "id": 15, "label": "证明意志"}, {
            "group": "Event",
            "id": 16,
            "label": "欢迎对话"
        }, {"group": "Event", "id": 17, "label": "考虑共商"}, {
            "group": "Event",
            "id": 18,
            "label": "贸易"
        }, {"group": "Event", "id": 19, "label": "经济"}, {"group": "Event", "id": 20, "label": "政策"}, {
            "group": "Event",
            "id": 21,
            "label": "对华贸易"
        }, {"group": "Event", "id": 22, "label": "做法"}, {"group": "Event", "id": 23, "label": "表示"}, {
            "group": "Event",
            "id": 24,
            "label": "基础"
        }, {"group": "高频词", "id": 25, "label": "高频词"}, {
            "group": "地名",
            "id": 26,
            "label": "地名",
        }, {"group": "人物", "id": 27, "label": "人物"}, {
            "group": "地名",
            "id": 28,
            "label": "美国"
        }, {"group": "人物", "id": 29, "label": "戴琪"}, {"group": "地名", "id": 30, "label": "中国"}],
        "links": [{'source': 0, 'label': '', 'target': 2}, {'source': 0, 'label': '', 'target': 25}, {
            'source': 0,
            'label': '',
            'target': 27
        }, {'source': 0, 'label': '', 'target': 26}, {'source': 2, 'label': '', 'target': 1}, {
            'source': 2,
            'label': '',
            'target': 13
        }, {'source': 13, 'label': '', 'target': 14}, {'source': 2, 'label': '', 'target': 18}, {
            'source': 25,
            'label': '',
            'target': 18
        }, {'source': 2, 'label': '', 'target': 19}, {'source': 25, 'label': '', 'target': 19}, {
            'source': 2,
            'label': '',
            'target': 20
        }, {'source': 20, 'label': '', 'target': 3}, {'source': 25, 'label': '', 'target': 20}, {
            'source': 2,
            'label': '',
            'target': 21
        }, {'source': 25, 'label': '', 'target': 21}, {'source': 2, 'label': '', 'target': 22}, {
            'source': 22,
            'label': '',
            'target': 12
        }, {'source': 25, 'label': '', 'target': 22}, {'source': 25, 'label': '', 'target': 23}, {
            'source': 25,
            'label': '',
            'target': 24
        }, {'source': 2, 'label': '', 'target': 28}, {'source': 28, 'label': '', 'target': 7}, {
            'source': 28,
            'label': '',
            'target': 8
        }, {'source': 28, 'label': '', 'target': 9}, {'source': 28, 'label': '', 'target': 17}, {
            'source': 25,
            'label': '',
            'target': 28
        }, {'source': 26, 'label': '', 'target': 28}, {'source': 28, 'label': '', 'target': 30}, {
            'source': 28,
            'label': '',
            'target': 29
        }, {'source': 2, 'label': '', 'target': 29}, {'source': 29, 'label': '', 'target': 3}, {
            'source': 29,
            'label': '',
            'target': 23
        }, {'source': 29, 'label': '', 'target': 5}, {'source': 29, 'label': '', 'target': 6}, {
            'source': 25,
            'label': '',
            'target': 29
        }, {'source': 27, 'label': '', 'target': 29}, {'source': 29, 'label': '', 'target': 28}, {
            'source': 29,
            'label': '',
            'target': 30
        }, {'source': 2, 'label': '', 'target': 30}, {'source': 30, 'label': '', 'target': 4}, {
            'source': 30,
            'label': '',
            'target': 10
        }, {'source': 30, 'label': '', 'target': 11}, {'source': 30, 'label': '', 'target': 15}, {
            'source': 30,
            'label': '',
            'target': 16
        }, {'source': 25, 'label': '', 'target': 30}, {'source': 26, 'label': '', 'target': 30}, {
            'source': 30,
            'label': '',
            'target': 28
        }, {'source': 30, 'label': '', 'target': 29}]


    }
    jsonmethod(jsontest);

    function jsonmethod(json) {
        // d3.json("graph.json", function (json) {
        root = json;
        // root = json;
        //给出节点id和初始化变量
        for (var i = 0; i < root.nodes.length; i++) {
            var node = root.nodes[i];
            // node.id = i;
            node.id = root.nodes[i].id;
            // console.log(root.nodes[i].name)
            node.name = root.nodes[i].label
            node.collapsing = 0;
            node.collapsed = false;
        }
        //给出链接id和初始化变量
        for (var i = 0; i < root.links.length; i++) {
            var link = root.links[i];
            link.source = root.nodes[link.source];
            link.target = root.nodes[link.target];
            link.id = i;
        }

        update();

    }

    function update() {
        //只保留可见的节点
        var nodes = root.nodes.filter(function (d) {
            return d.collapsing === 0;
        });
        var links = root.links;
        //只保留可见的链接
        links = root.links.filter(function (d) {
            return d.source.collapsing === 0 && d.target.collapsing === 0;
        });

        force
            .nodes(nodes)
            .links(links)
            .start();

        // Update the links…
        link = link.data(links, function (d) {
            return d.id;
        });
        // link.enter().append("g").append("circle")

        // Exit any old links.
        link.exit().remove();

        // Enter any new links.
        link.enter()
            // .append("g")
            .insert("line", ".node")
            .attr("class", "link")
            .attr("x1", function (d) {
                return d.source.x;
            })
            .attr("y1", function (d) {
                return d.source.y;
            })
            .attr("x2", function (d) {
                return d.target.x;
            })
            .attr("y2", function (d) {
                return d.target.y;
            })
            .attr("marker-end", "url(#arrow)");

        // Update the nodes…
        node = node.data(nodes, function (d) {
            return d.id;
        });

        // Exit any old nodes.
        node.exit().remove();

        // Enter any new nodes.
        node.enter()
            // .append("g")
            .append("circle")
            .attr("class", "node")
            .attr("cx", function (d) {
                return d.x;
            })
            .attr("cy", function (d) {
                return d.y;
            })
            .attr("r", function (d) {
                // return Math.sqrt(d.size) / 10 || 4.5;
                return Math.sqrt(d.size) / 10 || 25;
            })
            // .style("fill", color)
            .style("fill", function (node) {
                var color;//圆圈背景色
                var link = links[node.index];
                if (node.group === "知识图谱") {
                    color = "#fd8d3c"
                    // } else if (node.group === "关键词"){|| node.group === "高频词" || node.group === "地名" || node.group === "人物" || node.group === "组织机构") {
                } else if (node.group === "关键词") {
                    color = "#F6E8E9";
                } else if (node.group === "人物") {
                    color = "#87CEFA";
                } else if (node.group === "组织机构") {
                    color = "#4682B4";
                } else if (node.group === "地名") {
                    color = "#5F9EA0";
                } else if (node.group === "高频词") {
                    color = "#98FB98";
                } else {
                    color = "#B0C4DE";
                }
                return color;
            })
            .on("click", click)
            // .attr("r", 25)//设置圆圈半径
            // .attr('dominant-baseline', 'middle')
            .call(force.drag);
        svg_text = svg_text.data(nodes, function (d) {
            return d.name;
        })
        svg_text.exit().remove();


        // text
        svg_text.enter()
            // .append("g")
            .append('text')
            // .style('fill', '#000')
            .attr('dominant-baseline', 'middle')
            .attr('text-anchor', 'middle')
            .style('fill', function (node) {
                var color;//文字颜色
                color = "#000"
                return color;
            })
            .text(function (d) {
                return d.name
            });
        svg.on("dblclick.zoom", null);
        svg_text
            .attr('x', function (d) {
                return d.x
            })
            .attr('y', function (d) {
                return d.y
            })
            .attr('dominant-baseline', 'middle')
            .attr('text-anchor', 'middle')
            .text(function (d) {
                return d.name
            });
    }

    function tick() {
        link.attr("x1", function (d) {
            return d.source.x;
        })
            .attr("y1", function (d) {
                return d.source.y;
            })
            .attr("x2", function (d) {
                return d.target.x;
            })
            .attr("y2", function (d) {
                return d.target.y;
            });

        node.attr("cx", function (d) {
            return d.x;
        })
            .attr("cy", function (d) {
                return d.y;
            });
        svg_text
            .attr('x', function (d) {
                return d.x
            })
            .attr('y', function (d) {
                return d.y
            });
    }

    // 将叶子节点涂成橙色，包裹为白色或蓝色 .
    // function color(d) {
    //     return d.collapsed ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
    // }

    // 在点击中切换孩子.
    function click(d) {
        // console.log(d.collapsed)
        if (!d3.event.defaultPrevented) {
            //检查链接是否来自这个节点，如果是，折叠
            root.links.forEach(function (l) {
                // console.log(l)
                if (l.source.id === d.id) {
                    if (d.collapsed) {
                        //2021 11 15 代码修改处
                        // 裙带关系二级节点隐藏
                        root.links.forEach(function (p) {
                            if (p.source.id === l.target.id) {
                                if (p.target.id !== d.id) {

                                    // if (l.target.id !== p.target.id) {
                                    //     console.log(p.target.id + "=======1======" + p.target.id)
                                    // }
                                    // 裙带关系二级节点隐藏
                                    root.links.forEach(function (q) {
                                        if (q.source.id === p.target.id) {
                                            if (q.target.id !== d.id) {
                                                // if (q.target.id !== p.target.id) {
                                                //     console.log(p.target.id + "=======1======" + p.target.id)
                                                // }
                                                q.target.collapsing--;
                                            }
                                        }
                                    })
                                    p.target.collapsing--;
                                }
                            }
                        })
                        l.target.collapsing--;
                    } else {
                        //裙带关系二级节点显示
                        root.links.forEach(function (p) {
                            if (p.source.id === l.target.id) {

                                if (p.target.id !== d.id) {
                                    // console.log(p.target.id + "=======1======" + p.target.id)
                                    // console.log("这是一条华丽的分割线=================显示1")
                                    // 裙带关系二级节点隐藏
                                    root.links.forEach(function (q) {
                                        if (q.source.id === p.target.id) {
                                            if (q.target.id !== d.id) {
                                                // if (q.target.id !== p.target.id) {
                                                //     console.log(p.target.id + "=======2======" + p.target.id)
                                                // }
                                                // console.log(l.target.id +"============="+ p.target.id)
                                                q.target.collapsing++;
                                            }
                                        }
                                    })
                                    p.target.collapsing++;
                                }
                            }
                        })
                        l.target.collapsing++;
                    }
                }
            });
            d.collapsed = !d.collapsed;
        }
        update();
    }

</script>